package com.iotechn.unimall.admin.api.warehouseGoods;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.iotechn.unimall.biz.service.config.ConfigBizService;
import com.iotechn.unimall.core.exception.AdminServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.data.domain.WarehouseGoodsDO;
import com.iotechn.unimall.data.dto.excel.SkuTotalPriceDTO;
import com.iotechn.unimall.data.mapper.PurchaseWarehouseOrderGoodsMapper;
import com.iotechn.unimall.data.mapper.WarehouseGoodsMapper;
import com.iotechn.unimall.data.model.Page;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class WarehouseGoodsServiceImpl implements WarehouseGoodsService {
    @Autowired
    private WarehouseGoodsMapper warehouseGoodsMapper;

    @Autowired
    private ConfigBizService configBizService;

    @Autowired
    private PurchaseWarehouseOrderGoodsMapper purchaseWarehouseOrderGoodsMapper;

    @Override
    public Page<WarehouseGoodsDO> list(Integer page, Integer limit, String title, Long adminId, Long warehouseId, Long skuId) throws ServiceException {
        Wrapper<WarehouseGoodsDO> wrapper = new EntityWrapper<WarehouseGoodsDO>();
        if (warehouseId != null) {
            wrapper.eq("warehouse_id", String.valueOf(warehouseId));
        }

        if (skuId != null) {
            wrapper.eq("sku_id", String.valueOf(skuId));
        }
        if (title != null && !title.equals("")) {
            wrapper.like("sku_bar_code", title).or().like("title", title);
        }
        Integer count = warehouseGoodsMapper.selectCount(wrapper);
        wrapper.groupBy(" warehouse_id,spu_id");
        wrapper.orderBy("warehouse_sku_stock", true);
        wrapper.setSqlSelect("ifnull(sum(allprice)/sum(goods_history_amount),0) as price",
                "ifnull(sum(warehouse_sku_stock),0) as allStock",
                "id", "warehouse_id AS warehouseId", "sku_id AS skuId", "unit,warehouse_sku_stock AS warehouseSkuStock", "admin_id AS adminId", "sku_bar_code AS skuBarCode",
                "title", "spu_id AS spuId", "img", "warehouse_name AS warehouseName", "goods_history_amount AS goodsHistoryAmount",
                "gmt_update AS gmtUpdate", "gmt_create AS gmtCreate");

        List<WarehouseGoodsDO> warehouseGoodsDOS = warehouseGoodsMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);

        List<Long> skuIds = warehouseGoodsDOS.stream().map(WarehouseGoodsDO::getSkuId).collect(Collectors.toList());
       /* List<SkuTotalPriceDTO> barCodeSkuTotalList = purchaseWarehouseOrderGoodsMapper.summaryGoodsWithPara(null, null, skuIds, null, warehouseId);

        Map<Long, Float> priceMap = barCodeSkuTotalList.stream().collect(Collectors.toMap(SkuTotalPriceDTO::getSkuId,
                SkuTotalPriceDTO::getPrice));
        //计算总价

        warehouseGoodsDOS.forEach(item -> {
            Long tempSkuId = item.getSkuId();
            item.setAvgPrice(0f);
            if (!CollectionUtils.isEmpty(priceMap) && priceMap.containsKey(tempSkuId)) {
                Float avgPrice = priceMap.get(tempSkuId);
                item.setAvgPrice(avgPrice);
            }

        });*/
        return new Page<>(warehouseGoodsDOS, page, limit, count);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WarehouseGoodsDO create(WarehouseGoodsDO warehouseGoodsDO, Long adminId) throws ServiceException {
        warehouseGoodsDO.setAdminId(adminId);
        Date now = new Date();
        warehouseGoodsDO.setGmtCreate(now);
        warehouseGoodsDO.setGmtUpdate(now);
        if (warehouseGoodsMapper.insert(warehouseGoodsDO) > 0) {
            warehouseGoodsDO.setId(warehouseGoodsDO.getId());
            return warehouseGoodsDO;
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String update(WarehouseGoodsDO warehouseGoodsDO, Long adminId) throws ServiceException {
        Long id = warehouseGoodsDO.getId();
        if (id == null) {
            return "fail";
        }
        Date now = new Date();
        warehouseGoodsDO.setGmtUpdate(now);
        if (warehouseGoodsMapper.updateById(warehouseGoodsDO) > 0) {
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String delete(Long id, Long adminId) throws ServiceException {
        if (warehouseGoodsMapper.deleteById(id) > 0) {
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);

    }

    @Override
    public WarehouseGoodsDO detail(Long id, Long adminId) throws ServiceException {
        // return warehouseGoodsMapper.selectById(id);
        List<WarehouseGoodsDO> warehouseGoodsDOS = warehouseGoodsMapper.selectList(new EntityWrapper<WarehouseGoodsDO>().eq("id", id).last("for update"));
        WarehouseGoodsDO warehouseGoodsDO = new WarehouseGoodsDO();
        if (!CollectionUtils.isEmpty(warehouseGoodsDOS)) {
            warehouseGoodsDO = warehouseGoodsDOS.get(0);
            if (warehouseGoodsDO != null && warehouseGoodsDO.getAlarm() == null) {
                Float alarm = configBizService.getCommonGoodsAlarm();
                warehouseGoodsDO.setAlarm(alarm);
            }
        }
        return warehouseGoodsDO;
    }

    @Override
    public List<WarehouseGoodsDO> goodsListByWarehouse(Long skuId, Long adminId) throws ServiceException {
        //List<WarehouseGoodsDO>  list=warehouseGoodsMapper.selectList();
        return null;
    }

    @Override
    public Page<WarehouseGoodsDO> listGoodsAlarm(Integer page, Integer limit, String title, Long adminId, Long warehouseId) throws ServiceException {
        Wrapper<WarehouseGoodsDO> wrapper = new EntityWrapper<WarehouseGoodsDO>();
        if (warehouseId != null) {
            wrapper.eq("warehouse_id", String.valueOf(warehouseId));
        }
        if (title != null && !title.equals("")) {
            wrapper.like("sku_bar_code", title).or().like("title", title);
        }
        Integer count = warehouseGoodsMapper.selectCount(wrapper);
        wrapper.orderBy("warehouse_sku_stock", false);
        wrapper.setSqlSelect(
                "id", "warehouse_id AS warehouseId", "sku_id AS skuId", "unit", "ifnull(warehouse_sku_stock,0) AS warehouseSkuStock", "admin_id AS adminId", "sku_bar_code AS skuBarCode",
                "title", "spu_id AS spuId", "img", "warehouse_name AS warehouseName",
                "gmt_update AS gmtUpdate", "gmt_create AS gmtCreate", "ifnull(alarm,0) as alarm");
        List<WarehouseGoodsDO> WarehouseGoodsDOS = warehouseGoodsMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
        return new Page<>(WarehouseGoodsDOS, page, limit, count);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateGoodsAlarm(Long id, Float alarm) throws ServiceException {
        if (id == null) {
            return "fail";
        }
        Date now = new Date();
        WarehouseGoodsDO warehouseGoodsDO = new WarehouseGoodsDO();
        warehouseGoodsDO.setAlarm(alarm);
        warehouseGoodsDO.setId(id);
        warehouseGoodsDO.setGmtUpdate(now);
        if (warehouseGoodsMapper.updateById(warehouseGoodsDO) > 0) {
            return "ok";
        }
        throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
    }

    @Override
    public Page<WarehouseGoodsDO> listStockAlarmGoods(Integer page, Integer limit, String title, Long adminId, Long warehouseId) throws ServiceException {
        Wrapper<WarehouseGoodsDO> wrapper = new EntityWrapper<WarehouseGoodsDO>();
        if (warehouseId != null) {
            wrapper.eq("warehouse_id", String.valueOf(warehouseId));
        }
        if (title != null && !title.equals("")) {
            wrapper.like("sku_bar_code", title).or().like("title", title);
        }
        Float alarm = configBizService.getCommonGoodsAlarm();
        wrapper.setSqlSelect(
                "id", "warehouse_id AS warehouseId", "sku_id AS skuId", "unit", "ifnull(warehouse_sku_stock,0) AS warehouseSkuStock", "admin_id AS adminId", "sku_bar_code AS skuBarCode",
                "title", "spu_id AS spuId", "img", "warehouse_name AS warehouseName",
                "gmt_update AS gmtUpdate", "gmt_create AS gmtCreate", "ifnull(alarm," + alarm + ") as alarm");
//        wrapper.having("warehouseSkuStock<{0} and warehouseSkuStock<>{1}", alarm, 0);
//        wrapper.orderBy("warehouse_sku_stock", false);
//        List<WarehouseGoodsDO> WarehouseGoodsDOS = warehouseGoodsMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
//        final String countKey = "count";
//        List<Object> countList = warehouseGoodsMapper.selectObjs(new EntityWrapper<WarehouseGoodsDO>().setSqlSelect("ifnull( warehouse_sku_stock, 0 ) AS warehouseSkuStock").having("warehouseSkuStock<{0} and warehouseSkuStock<>{1}", alarm, 0));
//        Long count = (countList == null) ? 0L : new Long(countList.size());

        wrapper.orderBy("warehouse_sku_stock", false);
        wrapper.andNew().lt("warehouse_sku_stock - alarm", 0);
        wrapper.andNew().ne("warehouse_sku_stock", 0).and().isNotNull("warehouse_sku_stock");
        Integer count = warehouseGoodsMapper.selectCount(wrapper);
        List<WarehouseGoodsDO> WarehouseGoodsDOS = warehouseGoodsMapper.selectPage(new RowBounds((page - 1) * limit, limit), wrapper);
        return new Page<>(WarehouseGoodsDOS, page, limit, count);
    }

    @Override
    public List<WarehouseGoodsDO> listStockAlarmGoodsByPara(String title, Integer limit, Long warehouseId) {
        Wrapper<WarehouseGoodsDO> wrapper = new EntityWrapper<WarehouseGoodsDO>();
        if (warehouseId != null) {
            wrapper.eq("warehouse_id", String.valueOf(warehouseId));
        }
        if (title != null && !title.equals("")) {
            wrapper.like("sku_bar_code", title).or().like("title", title);
        }
        Float alarm = configBizService.getCommonGoodsAlarm();
        wrapper.setSqlSelect(
                "id", "warehouse_id AS warehouseId", "sku_id AS skuId", "unit", "ifnull(warehouse_sku_stock,0) AS warehouseSkuStock", "admin_id AS adminId", "sku_bar_code AS skuBarCode",
                "title", "spu_id AS spuId", "img", "warehouse_name AS warehouseName",
                "gmt_update AS gmtUpdate", "gmt_create AS gmtCreate", "ifnull(alarm," + alarm + ") as alarm");
        wrapper.orderBy("warehouse_sku_stock", false);
        wrapper.andNew().lt("warehouse_sku_stock - alarm", 0);
        wrapper.andNew().ne("warehouse_sku_stock", 0).and().isNotNull("warehouse_sku_stock");
        wrapper.last("limit  " + limit + "");
        List<WarehouseGoodsDO> warehouseGoodsDOS = warehouseGoodsMapper.selectList(wrapper);
        return !CollectionUtils.isEmpty(warehouseGoodsDOS) ? warehouseGoodsDOS : new LinkedList<>();
    }

}